package com.bjtang.filePaste;

import java.awt.AWTException;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.HashSet;
import java.util.Base64.Decoder;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.swing.KeyStroke;

import com.baidu.translate.demo.BaiduMain;

import com.tulskiy.keymaster.common.HotKey;
import com.tulskiy.keymaster.common.HotKeyListener;
import com.tulskiy.keymaster.common.Provider;

import net.coobird.thumbnailator.Thumbnails;

/**
 * 2024.3.4 bjtang@bjtang.com 功能说明 完成各项快捷键插件
 */
public class App {
	private List<String> in1;
	private List<String> in2;
	private MyWindow window = new MyWindow();

	public static void main(String[] args) throws InterruptedException {
		App app2 = new App();
		app2.initWindow();

	}

	private void initWindow() {
		// 主类是Provider,获取当前平台（操作系统）的提供者
		// Provider provider = Provider.getCurrentProvider(useSwingEventQueue);
		Provider provider = Provider.getCurrentProvider(true);
		// 注册热键,键值是以字符串的形式传递的
		// D 还原配置
		provider.register(KeyStroke.getKeyStroke("control alt D"), new HotKeyListener() {
			@Override
			public void onHotKey(HotKey arg0) {
				try {
					Thread.sleep(200); // 参数为毫秒，所以需要将0.3转换成对应的毫秒值
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				String paste = getPaste();
//				System.err.println(paste + "ok");
				String phone = getPhone(paste);
//				System.err.println(phone + "good");
				setPaste(phone);
			}
		});
		// F 重载为 X号模式
		provider.register(KeyStroke.getKeyStroke("control alt F"), new HotKeyListener() {
			@Override
			public void onHotKey(HotKey arg0) {
				try {
					Thread.sleep(200); // 参数为毫秒，所以需要将0.3转换成对应的毫秒值
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				String paste = getPaste();
//				System.err.println(paste + "ok");
				String x = getX(paste);
//				System.err.println(x + "good");
				setPaste(x);
			}
		});
		// V 重载为 虚拟主叫模式
		provider.register(KeyStroke.getKeyStroke("control alt V"), new HotKeyListener() {
			@Override
			public void onHotKey(HotKey arg0) {
				try {
					Thread.sleep(200); // 参数为毫秒，所以需要将0.3转换成对应的毫秒值
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				String paste = getPaste();
				String virtually = getVirtually(paste);
				setPaste(virtually);
			}
		});
		// 读粘贴板
		provider.register(KeyStroke.getKeyStroke("control alt C"), new HotKeyListener() {
			@Override
			public void onHotKey(HotKey arg0) {
				try {
					Thread.sleep(200); // 参数为毫秒，所以需要将0.3转换成对应的毫秒值
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				String paste = getPaste();
				in2 = in1;
				String[] split = paste.split("\\s");
				List<String> strings = new ArrayList<String>();
				for (String s : split) {
					if (s.trim().length() > 0)
						strings.add(s.trim());
				}
				in1 = strings;
//				System.err.println(in1);
//				System.err.println(in2);
			}
		});
		// 得到交集并集补集
		provider.register(KeyStroke.getKeyStroke("control alt X"), new HotKeyListener() {
			@Override
			public void onHotKey(HotKey arg0) {
				System.err.println("control alt X");
				setPaste();
			}
		});

		// 查单词
		provider.register(KeyStroke.getKeyStroke("control alt Q"), new HotKeyListener() {
			@Override
			public void onHotKey(HotKey arg0) {
				try {
					Thread.sleep(200); // 参数为毫秒，所以需要将0.3转换成对应的毫秒值
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				String paste = getPaste();
				String trans = BaiduMain.getTrans(paste);
				Point p = MouseInfo.getPointerInfo().getLocation();
				window.setLocation((int) p.getX(), (int) p.getY());
				window.setVisible(true);
				window.clearText();
				// window.writeText(paste);
				window.writeText(trans);
			}
		});

		// 转换图片和base64编码 image
		provider.register(KeyStroke.getKeyStroke("control alt I"), new HotKeyListener() {
			@Override
			public void onHotKey(HotKey arg0) {
				try {
					Thread.sleep(300); // 参数为毫秒，所以需要将0.3转换成对应的毫秒值
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				try {
					BufferedImage imageFromClipboard = Paste.getImageFromClipboard();
					// 从粘贴板中取得对象，如果为空则判断复制了文本
					if (imageFromClipboard == null) {
						String trim = Paste.getSysClipboardText().trim();
						// 如果长度过短，则判断是复制了文件路径
						if (trim.length() < 100) {
							toBase64(trim);
						} else {
							toImages(trim);
						}
					} else {
						toBase64(imageFromClipboard);
					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});

		// 转换GIF图片和base64编码 image
		provider.register(KeyStroke.getKeyStroke("control alt O"), new HotKeyListener() {
			@Override
			public void onHotKey(HotKey arg0) {
				try {
					Thread.sleep(300); // 参数为毫秒，所以需要将0.3转换成对应的毫秒值
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				try {
					BufferedImage imageFromClipboard = Paste.getImageFromClipboard();
					// 从粘贴板中取得对象，如果为空则判断复制了文本
					if (imageFromClipboard == null) {
						String trim = Paste.getSysClipboardText().trim();
						// 如果长度过短，则判断是复制了文件路径
						if (trim.length() < 100) {
							toBase64GIF(trim);
						} else {
							toImagesGIF(trim);
						}
					} else {
						toBase64GIF(imageFromClipboard);
					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
	}

	public String getPaste() {
		Robot robot;
		try {
			robot = new Robot();
			robot.keyPress(KeyEvent.VK_CONTROL); // 按下ctrl键盘
			robot.keyPress(KeyEvent.VK_C); // 按下ctrl键盘
			robot.delay(50);
			robot.keyRelease(KeyEvent.VK_CONTROL);
			robot.keyRelease(KeyEvent.VK_C);
			robot.delay(100);
		} catch (AWTException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

//		in2 = in1;
//		String sysClipboardText = Paste.getSysClipboardText();
//		String[] split = sysClipboardText.split("\\s");
//		List<String> strings = new ArrayList<String>();
//		for (String s : split) {
//			strings.add(s.trim());
//		}
//		this.in1 = strings;
//		return sysClipboardText;

		return Paste.getSysClipboardText().trim();
	}

	public void setPaste(String s) {
		Paste.setSysClipboardText(s);
		Robot robot;
		try {
			robot = new Robot();
			robot.delay(50);
			robot.keyPress(KeyEvent.VK_CONTROL); // 按下ctrl键盘
			robot.keyPress(KeyEvent.VK_V);
			robot.delay(50);
			robot.keyRelease(KeyEvent.VK_CONTROL);
			robot.keyRelease(KeyEvent.VK_V);
		} catch (AWTException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public String getPhone(String string) {
		// 拿到粘贴板内容
		String returnString = "";
		// 匹配数字 : ; , 空格
//		    Pattern pattern = Pattern.compile("[0-9:;,\\s]*"); 
		// 匹配数字 ,空格 说明是有前缀的主叫列表
		Pattern pattern3 = Pattern.compile("[0-9\\s]*");
		if (pattern3.matcher(string).matches()) {
			// 各个系统版本都支持换行分隔符
			String[] split = string.split("\\s");
			for (String s : split) {
				// 七位前缀
				if (s.trim().length() >= 11) {
					returnString = returnString + s.trim().substring(s.trim().length() - 11) + System.lineSeparator();
				} else {
					// 原样输出
					// returnString = returnString + s.trim()+ System.lineSeparator();
				}
			}
			return returnString.trim();
		}
		// 匹配数字 , 空格 说明是X号主叫
		Pattern pattern = Pattern.compile("[0-9,\\s]*");
		if (pattern.matcher(string).matches()) {
			String[] split = string.split(",");
			for (String s : split) {
				returnString = returnString + s.trim() + System.lineSeparator();
			}
			// System.err.println(returnString.trim());
			return returnString.trim();
		}
		// 匹配数字 : ; 空格 说明是虚拟主叫
		Pattern pattern2 = Pattern.compile("[0-9:;\\s]*");
		if (pattern2.matcher(string).matches()) {
			String[] split = string.split(";");
			for (String s : split) {
				returnString = returnString + s.trim() + System.lineSeparator();
			}
			// System.err.println(returnString.trim());
			int index = returnString.indexOf(":");
			returnString = returnString.substring(index + 1);
			return returnString.trim();
		}
		return returnString.trim();
	}

	public String getX(String string) {
		// 拿到粘贴板内容
		String returnString = "";
		// 匹配数字 ,空格 说明是有前缀的主叫列表
		Pattern pattern3 = Pattern.compile("[0-9\\s]*");
		if (pattern3.matcher(string).matches()) {
			// 各个系统版本都支持换行分隔符 windows,linux
			String[] split = string.split("\\s");
			for (String s : split) {
				if (s.length() >= 11)
					returnString = returnString + s.trim().substring(s.trim().length() - 11) + ',';
			}
			if (returnString.length() > 1)
				return returnString.substring(0, returnString.length() - 1);
		}
		return returnString;
	}

	public String getVirtually(String string) {
		// 拿到粘贴板内容
		String returnString = "";
		// 匹配数字 ,空格 说明是有前缀的主叫列表
		Pattern pattern3 = Pattern.compile("[0-9\\s]*");
		String title = "";
		if (pattern3.matcher(string).matches()) {
			// 各个系统版本都支持换行分隔符
			String[] split = string.split("\\s");
			title = split[0].trim();
			for (String s : split) {
				returnString = returnString + title + s.trim() + ';';
			}
			returnString = title + ":"
					+ returnString.substring(title.length() + title.length() + 1, returnString.length() - 1);
		}
		return returnString.trim();
	}

	public void setPaste() {
		if (in1 == null || in2 == null) {
			return;
		}
		List<String> strings = new ArrayList<String>(in1);
		// 求交集
		strings.retainAll(in2);
		List<String> strings2 = new ArrayList<String>(in1);
		// 求并集
		strings2.removeAll(in2);
		strings2.addAll(in2);
		List<String> strings3 = new ArrayList<String>(strings2);
		// 求补集(并集差)
		strings3.removeAll(strings); // a c
		List<String> findDifference = findDifference(strings,strings2);
		List<String> findDifference2 = findDifference(strings2,strings);
		Paste.setSysClipboardText("交集" + strings.size() + "并集" + strings2.size() + "求差" + findDifference.toString()+"求差2"+findDifference2.toString());
	}
	/*
	 * 两个[]String 求差 例如["1","2","3"] ["3","4"] 则差为["1","2"]
	 */
	public static List<String> findDifference(List<String> array1, List<String> array2) {
		// 使用 HashSet 存储第二个数组的元素，便于快速查找
		Set<String> set2 = new HashSet<>(array2);
		// 使用 ArrayList 存放差异结果
		List<String> differenceList = new ArrayList<>();

		// 遍历第一个数组，检查每个元素是否不在第二个数组的集合中
		for (String element : array1) {
			if (!set2.contains(element)) {
				differenceList.add(element);
			}
		}

		return differenceList;
	}
	public void toImages(String string) {
		try {
			int indexOf = string.indexOf("data");
			if (indexOf >= 0) {
				string = string.substring("data:image/jpeg;base64,".length());
			}
			Decoder decoder2 = Base64.getDecoder();
			byte[] decode = decoder2.decode(string);
			ByteArrayInputStream bis = new ByteArrayInputStream(decode);
			BufferedImage image = ImageIO.read(bis);
			Paste.setClipboardImage(image);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/*
	 * 读取剪切板方式
	 */
	public void toBase64(BufferedImage image) {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		// 如果估算大小大于500k，则进行有损压缩，否则无损，反复压缩可能导致图像过于模糊
		try {
			if (getImageSize(image) > (1024 * 500)) {
				Thumbnails.of(image).scale(1.0) // 根据需求调整缩放比例或尺寸
						.outputQuality(0.6) // 设置JPEG质量
						.outputFormat("jpeg") // 设置图片格式 Thumbnails不支持png,请使用jpg或者jpeg
						.toOutputStream(bos);
			} else {
				ImageIO.write(image, "png", bos);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		byte[] byteArray = bos.toByteArray();
		String encodeToString = Base64.getEncoder().encodeToString(byteArray);
		// 输出base64编码到剪切板
		Paste.setSysClipboardText("data:image/jpeg;base64," + encodeToString);
	}

	/*
	 * 读取文件方式
	 */
	public void toBase64(String fileString) {
		// 在linux可能为 file:///home/bjtang/图片/Screenshot_20240312_233916.png
		// 需要首先进行转换
		int indexOf = fileString.indexOf("file://");
		if (indexOf >= 0) {
			fileString = fileString.substring("file://".length());
		}
		try {
			File inputFile = new File(fileString);
			BufferedImage originalImage = ImageIO.read(inputFile);
			toBase64(originalImage);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 在Java中，BufferedImage对象的大小（即占用内存存储）并不直接提供一个API来获取。但是，你可以通过计算图像像素数量乘以每个像素的字节数来估算其内存占用。
	 * 对于不带Alpha通道的RGB图像，每个像素通常占用3个字节（红、绿、蓝各1字节）。如果图像有Alpha通道，则每个像素占用4个字节（红、绿、蓝、透明度各1字节）。
	 */
	public long getImageSize(BufferedImage image) {
		int width = image.getWidth();
		int height = image.getHeight();
		// 获取图像类型并判断是否包含Alpha通道
		int type = image.getType();
		boolean hasAlpha = (type == BufferedImage.TYPE_4BYTE_ABGR || type == BufferedImage.TYPE_4BYTE_ABGR_PRE
				|| type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_ARGB_PRE);
		double bytesPerPixel = hasAlpha ? 4.0 : 3.0; // 带Alpha通道或不带Alpha通道
		long estimatedSizeInBytes = (long) (width * height * bytesPerPixel);
		return estimatedSizeInBytes;
	}

	/*
	 * 读取剪切板方式
	 */
	public void toBase64GIF(BufferedImage image) {
		//TODO
	}

	/*
	 * 读取文件方式
	 */
	public void toBase64GIF(String fileString) {
		System.err.println("先执行的这里");
		// 在linux可能为 file:///home/bjtang/图片/Screenshot_20240312_233916.png
		// 需要首先进行转换
		int indexOf = fileString.indexOf("file://");
		if (indexOf >= 0) {
			fileString = fileString.substring("file://".length());
		}
		try {
			Path gifPath = Paths.get(fileString);
			byte[] gifBytes = Files.readAllBytes(gifPath);
			// 将 GIF 图像文件内容转换为 Base64 编码字符串
			String base64String = Base64.getEncoder().encodeToString(gifBytes);
			Paste.setSysClipboardText("data:image/gif;base64," + base64String);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void toImagesGIF(String string) {
		try {
			int indexOf = string.indexOf("data");
			if (indexOf >= 0) {
				string = string.substring("data:image/gif;base64,".length());
			}
			Decoder decoder2 = Base64.getDecoder();
			byte[] decode = decoder2.decode(string);
			ByteArrayInputStream bis = new ByteArrayInputStream(decode);
			BufferedImage image = ImageIO.read(bis);
			Paste.setClipboardImage(image);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}